﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */

#region Using
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.ServiceModel.DomainServices.Server;
using Lucene.Net.Analysis.Fr;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using NetBay.Core.BusinessEntities;
using NetBay.Core.Extensions;
using NetBay.Core.Mail.SMTP.Assync;
using Rio.Applications.Web.Services.BusinessEntities;
using Rio.Doc.Business.Repository;
using Rio.Framework.RioManager;
using NetBay.Core.BusinessEntities.Versioning;
using NetBay.Core.BusinessEntities.Workflow;
using System.Configuration;
#endregion

namespace Rio.Applications.Web.Services
{
    /// <summary>
    /// Class to handle Business entities in a RIA services
    /// </summary>
    public partial class BusinessEntitiesDomainService : DomainService
    {
        /// <summary>
        /// Gets the get document rank.
        /// </summary>
        /// <value>The get document rank.</value>
        private bool GetDocumentRank
        {
            get
            {
                if (ConfigurationManager.AppSettings.Get("DocumentRankInsertMode") != null)
                {
                    return Convert.ToBoolean(ConfigurationManager.AppSettings.Get("DocumentRankInsertMode"));
                }
                return false;
            }
        }


        /// <summary>
        /// Update document's rank
        /// </summary>
        /// <param name="p_sDocumentNewRank">The documents and thier new ranks. RD_NO;RANK;#RD_NO;RANK;#RD_NO;RANK;#RD_NO;RANK;#</param>
        /// <returns>Status of execution</returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<ReturnBoolean> UpdateDocumentRank(string p_sDocumentNewRank)
        {
            List<ReturnBoolean> l_oReturnBooleans = new List<ReturnBoolean>();
            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_sDocumentNewRank<" + p_sDocumentNewRank + ">");

                // We have [RdNo;Order#]
                var l_aSplit = p_sDocumentNewRank.Split(new[] {'#'});
                foreach (string l_szItem in l_aSplit)
                {
                    // We have RdNo;Order
                    var l_aSplitItem = l_szItem.Split(new[] {';'});
                    if (l_aSplitItem.Count() >= 2)
                    {
                        var l_lFolderID = Convert.ToInt64(l_aSplitItem[0]);
                        // Add a historic of user action
                        AddActionHistoric((int)Constant.UserActions.REORGANISATION_DOSSIER, 0, l_lFolderID, null, null);
                    }
                }
                var l_oReturnBoolean = DocumentRepository.UpdateDocumentRank(p_sDocumentNewRank);
                l_oReturnBooleans.Add(l_oReturnBoolean);
            }
            catch (Exception ex)
            {
                var l_oReturnBoolean = new ReturnBoolean("(<p_sDocumentNewRank"+p_sDocumentNewRank+">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in UpdateDocumentRank : " + l_oReturnBoolean.FullErrorMessage);
                l_oReturnBooleans.Add(l_oReturnBoolean);
            }

            return l_oReturnBooleans;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_sMailSubject">Mail subject</param>
        /// <param name="p_sBody">Mail body</param>
        /// <param name="p_oMailAdressToList">Mail adresses</param>
        /// <param name="p_oFilesName">Attach files</param>
        /// <param name="p_oOriginalFileName"></param>
        [Invoke(HasSideEffects = true)]
        public void UpdateDocumentsForFullText(string p_sDocumentList)
        {
            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_sDocumentList<" + p_sDocumentList + ">)...");
                // Retreive info from document
                DocumentRepository.UpdateDocumentsForFullText(p_sDocumentList);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in UpdateDocumentsForFullText : " + ex.Message);
            }
        }
                
        /// <summary>
        /// Update documents item
        /// </summary>
        /// <param name="p_lDocumentId">Document ID</param>
        /// <param name="p_szItem">Document Item</param>
        /// <returns>Status of execution</returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<ReturnBoolean> UpdateDocumentItem(long p_lFolderTypeID, long p_lFolderId, long p_lDocumentId, string p_szItem)
        {
            var l_oReturnBooleans = new List<ReturnBoolean>();
            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocumentId<" + p_lDocumentId + "> p_szItem<" + p_szItem + ">)");

                // Retreive info from document
                var l_oDocument = DocumentRepository.GetDocumentById(p_lDocumentId);

                // Add a historic of user action
                AddActionHistoric((int)Constant.UserActions.CLASSEMENT_DOSSIER, 0, 0, l_oDocument.FolderIdentifier, l_oDocument.OriginalNameFile);
                
                var l_oRet = DocumentRepository.UpdateDocumentItem(p_lDocumentId, p_szItem);
                l_oReturnBooleans.Add(l_oRet);

                // Call workflow Controller 
                WorkflowController.StartWorkflowDispatcher(p_lFolderTypeID, p_lFolderId, wkfConditionType.UpdateDocumentItem, GetUser().UserId);

            }
            catch (Exception ex)
            {
                var l_oRet = new ReturnBoolean("(p_lDocumentId<" + p_lDocumentId + "> p_szItem<" + p_szItem + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in UpdateDocumentItem : " + l_oRet.FullErrorMessage);
                l_oReturnBooleans.Add(l_oRet);
            }

            return l_oReturnBooleans;
        }

        /// <summary>
        /// Retreive all documents from a messageflow 
        /// </summary>
        /// <param name="p_lMessageFlowID">Message flow iedntifier </param>
        /// <returns>List of Documents</returns>
        [Query]
        public IEnumerable<Document> GetDocumentByMessageFlow(long p_lMessageFlowID )
        {
            var l_oDocuments = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lMessageFlowID<" + p_lMessageFlowID + ">)...");
                l_oDocuments = DocumentRepository.GetDocumentByMessageFlow(p_lMessageFlowID);
            }
            catch (Exception ex)
            {
                var l_oDocument = new Document("(p_lMessageFlowID<" + p_lMessageFlowID + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetDocumentByMessageFlow : " + l_oDocument.FullErrorMessage);
                l_oDocuments.Add(l_oDocument);
            }
            return l_oDocuments;
        }

        /// <summary>
        /// Retreive documents for a message flow by by state
        /// </summary>
        /// <param name="p_lGroupId">Group ID</param>
        /// <param name="p_lMsgFlowId">MessageFlow ID</param>
        /// <param name="p_iFilteredByState">State of the p_i filtered by.</param>
        /// <returns>
        /// Historical
        /// </returns>
        [Query]
        public IEnumerable<Document> GetDocumentByGroupMessageFlow(long p_lGroupId, long p_lMsgFlowId, int p_iFilteredByState)
        {
            List<Document> l_oRet = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lGroupId<" + p_lGroupId + "> p_lMsgFlowId<" + p_lMsgFlowId + "> p_iFilteredByState<" + p_iFilteredByState + ">)...");
                l_oRet = DocumentRepository.GetDocumentByGroupMessageFlow(p_lGroupId, p_lMsgFlowId, p_iFilteredByState);
            }
            catch (Exception ex)
            {
                Document l_oReturnValue = new Document("(p_lGroupId<" + p_lGroupId + "> p_lMsgFlowId<" + p_lMsgFlowId + "> p_iFilteredByState<" + p_iFilteredByState + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oReturnValue.FullErrorMessage);
                l_oRet.Add(l_oReturnValue);
            }
            return l_oRet;
        }
        
        /// <summary>
        /// Retreive all documents included in a folder
        /// </summary>
        /// <param name="p_lFolderTypeID">FolderType ID</param>
        /// <param name="p_lFolderId">Folder ID</param>
        /// <returns>List of Documents</returns>
        [Query]
        public IEnumerable<Document> GetDocuments(long p_lFolderTypeID, long p_lFolderId)
        {
            var l_oDocuments = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lFolderTypeID<" + p_lFolderTypeID + "> p_lFolderId<" + p_lFolderId + ">)...");
                var l_oUser = GetUser();

                l_oDocuments = DocumentRepository.GetDocumentByFolder(l_oUser.UserId, p_lFolderTypeID, p_lFolderId);
            }
            catch (Exception ex)
            {
                var l_oDocument = new Document("(p_lFolderTypeID<" + p_lFolderTypeID + "> p_lFolderId<" + p_lFolderId + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetDocuments : " + l_oDocument.FullErrorMessage);
                l_oDocuments.Add(l_oDocument);
            }
            return l_oDocuments;
        }



        /// <summary>
        /// Retreive all deleted documents included in a folder
        /// </summary>
        /// <param name="p_lFolderTypeID">FolderType ID</param>
        /// <param name="p_lFolderId">Folder ID</param>
        /// <returns>List of Documents</returns>
        [Query]
        public IEnumerable<Document> GetDeletedDocuments(long p_lFolderTypeID, long p_lFolderId)
        {
            var l_oDocuments = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lFolderTypeID<" + p_lFolderTypeID + "> p_lFolderId<" + p_lFolderId + ">)...");
                var l_oUser = GetUser();

                l_oDocuments = DocumentRepository.GetDeletedDocumentByFolder(l_oUser.UserId, p_lFolderTypeID, p_lFolderId);
            }
            catch (Exception ex)
            {
                var l_oDocument = new Document("(p_lFolderTypeID<" + p_lFolderTypeID + "> p_lFolderId<" + p_lFolderId + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetDeletedDocumentByFolder : " + l_oDocument.FullErrorMessage);
                l_oDocuments.Add(l_oDocument);
            }
            return l_oDocuments;
        }


        /// <summary>
        /// Delete a document
        /// </summary>
        /// <param name="p_oListDocumentId">List of Document identifier</param>
        [Query(HasSideEffects=true)]
        public IEnumerable<ReturnObject> DeleteDocuments(List<long> p_oListDocumentId)
        {
            var l_oReturnObjects = new List<ReturnObject>();

            try
            {
                foreach (long DocId in p_oListDocumentId)
                {                    
                    // Retreive info from document
                    var l_oDocument = DocumentRepository.GetDocumentById(DocId);
                    long l_oFolderId = 0;

                    AddActionHistoric((int)Constant.UserActions.SUPPRESSION_IMAGE, l_oDocument.FolderTypeIdentifier, long.TryParse(l_oDocument.FolderIdentifier, out l_oFolderId) ? l_oFolderId : 0, l_oDocument.Identifier.ToString(), l_oDocument.OriginalNameFile);
                    
                    NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocumentId<" + DocId + ">)...");
                    DocumentRepository.DeleteDocument(DocId);
                }
            }
            catch (Exception ex)
            {
                var l_oReturnObject = new ReturnObject(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in DeleteDocument : " + ex.Message);
                l_oReturnObjects.Add(l_oReturnObject);
            }
            return l_oReturnObjects;
        }

        /// <summary>
        /// Removes the documents.
        /// </summary>
        /// <param name="p_oListDocumentId">The p_o list document id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<ReturnObject> RemoveDocuments(List<long> p_oListDocumentId)
        {
            var l_oReturnObjects = new List<ReturnObject>();

            try
            {
                foreach (long DocId in p_oListDocumentId)
                {
                    // Retreive info from document
                    var l_oDocument = DocumentRepository.GetDocumentById(DocId);
                    long l_oFolderId = 0;

                    AddActionHistoric((int)Constant.UserActions.SUPPRESSION_IMAGE, l_oDocument.FolderTypeIdentifier, long.TryParse(l_oDocument.FolderIdentifier, out l_oFolderId) ? l_oFolderId : 0, l_oDocument.Identifier.ToString(), l_oDocument.OriginalNameFile);

                    NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocumentId<" + DocId + ">)...");
                    DocumentRepository.RemoveDocument(DocId);
                }
            }
            catch (Exception ex)
            {
                var l_oReturnObject = new ReturnObject(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in RemoveDocuments : " + ex.Message);
                l_oReturnObjects.Add(l_oReturnObject);
            }
            return l_oReturnObjects;
        }

        /// <summary>
        /// Remove a document
        /// </summary>
        /// <param name="p_lDocumentId">Document identifier</param>
        [Query]
        public IEnumerable<ReturnObject> DeleteDocument(long p_lDocumentId)
        {
            var l_oReturnObjects = new List<ReturnObject>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocumentId<" + p_lDocumentId + ">)...");
                DocumentRepository.DeleteDocument(p_lDocumentId);
            }
            catch (Exception ex)
            {
                var l_oReturnObject = new ReturnObject(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in DeleteDocument : " + ex.Message);
                l_oReturnObjects.Add(l_oReturnObject);
            }
            return l_oReturnObjects;
        }

        /// <summary>
        /// Remove a document
        /// </summary>
        /// <param name="p_lDocumentId">Document identifier</param>
        [Query]
        public IEnumerable<ReturnObject> RemoveDocument(long p_lDocumentId)
        {
            var l_oReturnObjects = new List<ReturnObject>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocumentId<" + p_lDocumentId + ">)...");
                DocumentRepository.RemoveDocument(p_lDocumentId);
            }
            catch (Exception ex)
            {
                var l_oReturnObject = new ReturnObject(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in DeleteDocument : " + ex.Message);
                l_oReturnObjects.Add(l_oReturnObject);
            }
            return l_oReturnObjects;
        }

        /// <summary>
        /// Restore a document
        /// </summary>
        /// <param name="p_oListDocumentId">List of Document identifier</param>
        [Invoke]
        public ReturnBoolean RestoreDocument(List<long> p_oListDocumentId)
        {
            var returnBoolean = new ReturnBoolean();

            try
            {
                foreach (long DocId in p_oListDocumentId)
                {
                    // Retreive info from document
                    var l_oDocument = DocumentRepository.GetDocumentById(DocId);
                    long l_oFolderId = 0;

                    AddActionHistoric((int)Constant.UserActions.RESTAURATION_IMAGE, l_oDocument.FolderTypeIdentifier, long.TryParse(l_oDocument.FolderIdentifier, out l_oFolderId) ? l_oFolderId : 0, l_oDocument.Identifier.ToString(), l_oDocument.OriginalNameFile);

                    NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocumentId<" + DocId + ">)...");
                    DocumentRepository.RestoreDocument(DocId);
                }

                returnBoolean.Value = true;
            }
            catch (Exception ex)
            {
                returnBoolean.ErrorMessage = ex.Message;
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in RestoreDocument : " + ex.Message);
                returnBoolean.Value = false;
            }

            return returnBoolean;
        }



        /// <summary>
        /// Update document's infos
        /// </summary>
        /// <param name="FolderTypeId">The folder type id.</param>
        /// <param name="FolderId">The folder id.</param>
        /// <param name="p_lDocumentId">Document ID</param>
        /// <param name="p_szNote">Notes</param>
        /// <param name="p_szAuthor">Author</param>
        /// <param name="p_szPhotoCredit">Photo credit</param>
        /// <returns>
        /// Status of execution
        /// </returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<ReturnObject> UpdateDocument(long FolderTypeId, long FolderId, long p_lDocumentId, string p_szNote, string p_szAuthor, string p_szPhotoCredit)
        {
            var l_oReturnObjects = new List<ReturnObject>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocumentId<" + p_lDocumentId + "> p_szNote<" + p_szNote + "> p_szAuthor<" + p_szAuthor + "> p_szPhotoCredit<" + p_szPhotoCredit + ">)...");
               
                // Retreive info from document
                var l_oDocument = DocumentRepository.GetDocumentById(p_lDocumentId);
                
                // Add a historic of user action
                AddActionHistoric((int)Constant.UserActions.AJOUT_NOTE, 0, 0, l_oDocument.FolderIdentifier, l_oDocument.OriginalNameFile);
                DocumentRepository.UpdateDocument(p_lDocumentId, p_szNote, p_szAuthor, p_szPhotoCredit);

                // Call workflow Controller 
                var docid = new List<long> { l_oDocument.Identifier };
                WorkflowController.StartWorkflowDispatcher(l_oDocument.FolderTypeIdentifier, FolderId, wkfConditionType.UpdateDocumentNote, GetUser().UserId, docid);

            }
            catch (Exception ex)
            {
                var l_oReturnObject = new ReturnObject(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in DeleteDocument : " + ex.Message);
                l_oReturnObjects.Add(l_oReturnObject);
            }
            return l_oReturnObjects;
        }

        /// <summary>
        /// Retreive all Folders that matches criterias 
        /// </summary>
        /// <param name="p_lOrganisationId"></param>
        /// <param name="p_lFolderTypeId">FolderType identifier</param>
        /// <param name="p_szNote">regular expression applied into document's note</param>
        /// <param name="p_szCreditPhoto">regular expression applied into creditPhoto's note</param>
        /// <param name="p_szAuteur"></param>
        /// <param name="p_szFichierOrigine"></param>
        /// <param name="p_bIsLazyLoading"></param>
        /// <returns>List of documents</returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<Document> SearchDocuments(long p_lOrganisationId, long p_lFolderTypeId, string p_szNote = null, string p_szCreditPhoto = null, string p_szAuteur = null, string p_szFichierOrigine = null, bool p_bIsLazyLoading = false)
        {
            var l_oDocuments = new List<Document>();
            var l_oDocumentsCopy = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_szNote<" + p_szNote + "> p_szCreditPhoto<" + p_szCreditPhoto + "> p_szAuteur<" + p_szAuteur + "> p_szFichierOrigine<" + p_szFichierOrigine + "> p_bIsLazyLoading<" + p_bIsLazyLoading + ">)...");

                var l_oFolderTypeRepository = new FolderTypeRepository();
                var l_oUser = GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);

                l_oDocuments = DocumentRepository.SearchDocuments(l_oUser.UserId, l_oFolderTypeRepository, p_szNote, p_szCreditPhoto, p_szAuteur, p_szFichierOrigine, p_bIsLazyLoading);

                if (l_oDocuments.Count > 0)
                {
                    var L_GroupList = new List<Group>(l_oUser.GroupList);
                    var L_bCanBeConsul = false;

                    foreach (Document L_oDocument in l_oDocuments)
                    {
                        if (L_oDocument.ItemRank.Equals("000000000000"))
                        {
                            l_oDocumentsCopy.Add(L_oDocument);
                        }
                        else
                        {
                            var L_oSelectedItemInTreeView = l_oFolderTypeRepository.LstItems.Where(x => x.Code.Equals(L_oDocument.ItemRank)).FirstOrDefault();

                            if (L_oSelectedItemInTreeView != null)
                            {
                                foreach (Group grp in L_GroupList)
                                {
                                    // TOSEEFORLATER : Not implemented right now in RIO but normally to do : "(if (grp.IsAdministrator) return true;)"
                                    var L_oItemRightsList = new List<ItemRights>(grp.ItemRightsList);

                                    var L_oSelectedItemRights = GetItemsRights(L_oItemRightsList, L_oSelectedItemInTreeView);
                                    if (L_oSelectedItemRights != null)
                                    {
                                        if (L_oSelectedItemRights.CanConsult)
                                        {
                                            L_bCanBeConsul = true;
                                            break;
                                        }
                                    }
                                }
                                if (L_bCanBeConsul)
                                {
                                    l_oDocumentsCopy.Add(L_oDocument);
                                    L_bCanBeConsul = false;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                var l_oDocument = new Document("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_szNote<" + p_szNote + "> p_szCreditPhoto<" + p_szCreditPhoto + ">p_bIsLazyLoading<" + p_bIsLazyLoading + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in SearchDocuments : " + l_oDocument.FullErrorMessage);
                l_oDocuments.Add(l_oDocument);
            }
            ToolsDS.CleanMemory();
            return l_oDocumentsCopy; 
        }
        
        /// <summary>
        /// This method Launch the necessary business method to combine a document search with a full search
        /// </summary>
        /// <param name="p_lOrganisationId">ID Organization</param>
        /// <param name="p_lFolderTypeId">ID FolderType</param>
        /// <param name="p_sOperator">Full search operator</param>
        /// <param name="sFullTextString">Full search string</param>
        /// <param name="p_szCultureName">Full search culture</param>
        /// <param name="p_szNote">Document note</param>
        /// <param name="p_szCreditPhoto">Document credit photo (Chrono)</param>
        /// <param name="p_szAuteur">Document Author</param>
        /// <param name="p_szFichierOrigine">Document name</param>
        /// <returns>A list of document</returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<Document> SearchDocumentsWithFullSearch(long p_lOrganisationId, long p_lFolderTypeId, string p_sOperator, string sFullTextString, string p_szCultureName, string p_szNote = null, string p_szCreditPhoto = null, string p_szAuteur = null, string p_szFichierOrigine = null)
        {
            var l_oDocuments_DocumentSearch = new List<Document>();
            var l_oDocuments_FullTextSearch = new List<Document>();
            var l_oDocuments_Final = new List<Document>();
            var l_oDocumentsCopy = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_szNote<" + p_szNote + "> p_szCreditPhoto<" + p_szCreditPhoto + "> p_szAuteur<" + p_szAuteur + "> p_szFichierOrigine<" + p_szFichierOrigine + ">)...");

                // DOCUMENT SEARCH: Get the list of document regarding to the document search information
                var l_oFolderTypeRepository = new FolderTypeRepository();
                var l_oUser = GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);
                if (!String.IsNullOrEmpty(p_szNote) || !String.IsNullOrEmpty(p_szFichierOrigine) || !String.IsNullOrEmpty(p_szCreditPhoto) || !String.IsNullOrEmpty(p_szAuteur))
                {
                    l_oDocuments_DocumentSearch = DocumentRepository.SearchDocuments(l_oUser.UserId, l_oFolderTypeRepository, p_szNote, p_szCreditPhoto, p_szAuteur, p_szFichierOrigine, true);
                }
                // FULLTEXT SEARCH: Get the list of document regarding to the full search
                l_oDocuments_FullTextSearch = SearchFullText(sFullTextString, p_szCultureName, p_lOrganisationId, p_lFolderTypeId) as List<Document>;
                if (!String.IsNullOrEmpty(p_szNote) || !String.IsNullOrEmpty(p_szFichierOrigine) || !String.IsNullOrEmpty(p_szCreditPhoto) || !String.IsNullOrEmpty(p_szAuteur))
                {
                    switch (p_sOperator)
                    {
                        case "AND":
                            //The case "AND" means that we return all the documents resulting of the full search having a corresponding Identifier into the document search results
                            foreach (Document l_oDoc in l_oDocuments_FullTextSearch)
                            {
                                var l_oDocument = l_oDocuments_DocumentSearch.Where(f => f.Identifier == l_oDoc.Identifier).FirstOrDefault();
                                if (l_oDocument != null)
                                {
                                    l_oDocuments_Final.Add(l_oDocument);
                                }
                            }
                            break;

                        case "OR":
                            //The case "OR" means that we return the documents of both search, removing identical documents
                            l_oDocuments_Final = l_oDocuments_DocumentSearch;
                            if (l_oDocuments_FullTextSearch != null && l_oDocuments_FullTextSearch.Count > 0)
                            {
                                foreach (Document l_oDoc in l_oDocuments_FullTextSearch)
                                {
                                    var l_oDocument = l_oDocuments_Final.Where(f => f.Identifier == l_oDoc.Identifier).FirstOrDefault();
                                    if (l_oDocument == null)
                                    {
                                        l_oDocuments_Final.Add(l_oDoc);
                                    }
                                }
                            }
                            break;
                    }
                }
                else
                {
                    l_oDocuments_Final = l_oDocuments_FullTextSearch;
                }

                if (l_oDocuments_Final.Count > 0)
                {
                    var L_GroupList = new List<Group>(l_oUser.GroupList);
                    var L_bCanBeConsul = false;

                    foreach (Document L_oDocument in l_oDocuments_Final)
                    {
                        if (L_oDocument.ItemRank.Equals("000000000000"))
                        {
                            l_oDocumentsCopy.Add(L_oDocument);
                        }
                        else
                        {
                            var L_oSelectedItemInTreeView = l_oFolderTypeRepository.LstItems.Where(x => x.Code.Equals(L_oDocument.ItemRank)).FirstOrDefault();

                            if (L_oSelectedItemInTreeView != null)
                            {
                                foreach (Group grp in L_GroupList)
                                {
                                    // TOSEEFORLATER : Not implemented right now in RIO but normally to do : "(if (grp.IsAdministrator) return true;)"
                                    var L_oItemRightsList = new List<ItemRights>(grp.ItemRightsList);

                                    var L_oSelectedItemRights = GetItemsRights(L_oItemRightsList, L_oSelectedItemInTreeView);
                                    if (L_oSelectedItemRights != null)
                                    {
                                        if (L_oSelectedItemRights.CanConsult)
                                        {
                                            L_bCanBeConsul = true;
                                            break;
                                        }
                                    }
                                }
                                if (L_bCanBeConsul)
                                {
                                    l_oDocumentsCopy.Add(L_oDocument);
                                    L_bCanBeConsul = false;
                                }
                            }
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                var l_oDocument = new Document("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_szNote<" + p_szNote + "> p_szCreditPhoto<" + p_szCreditPhoto + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in SearchDocumentsWithFullSearch : " + l_oDocument.FullErrorMessage);
                l_oDocuments_Final.Add(l_oDocument);
            }
            ToolsDS.CleanMemory();
            return l_oDocumentsCopy;
        }

        /// <summary>
        /// This method Launch the necessary business method to combine a document search with a full search
        /// </summary>
        /// <param name="p_lOrganisationId">ID Organization</param>
        /// <param name="p_lFolderTypeId">ID FolderType</param>
        /// <param name="p_sOperator">Full search operator</param>
        /// <param name="p_sFullTextString">Full search string</param>
        /// <param name="p_szCultureName">Full search culture</param>
        /// <param name="p_oCriteriaFilter">Folder search criterias</param>
        /// <returns></returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<Folder> GetFoldersWithFullSearch(long p_lOrganisationId, long p_lFolderTypeId, string p_sOperator, string p_sFullTextString, string p_szCultureName, Dictionary<long, string> p_oCriteriaFilter = null)
        {
            var l_oFolders_FolderSearch = new List<Folder>();
            var l_oFolders_FullTextSearch = new List<Folder>();
            var l_oDocuments_FullTextSearch = new List<Document>();
            var l_oFolders_Final = new List<Folder>();
            var l_oDocumentsCopy = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_sOperator<" + p_sOperator + "> p_sFullTextString<" + p_sFullTextString + ">)...");
                var l_oFolderTypeRepository = new FolderTypeRepository();
                var l_oUser = GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);

                // FOLDER SEARCH: Get the list of folder regarding to the folder search criteria
                var l_oCriteria = p_oCriteriaFilter.Where(item => item.Value != null && !String.Empty.Equals(item.Value)).FirstOrDefault().Value;
                if (!String.IsNullOrEmpty(l_oCriteria))
                {
                    l_oFolders_FolderSearch = GetFolders(p_lOrganisationId, p_lFolderTypeId, p_oCriteriaFilter) as List<Folder>;
                }            
                // FULLTEXT SEARCH: Get the list of document regarding to the full search
                l_oDocuments_FullTextSearch = SearchFullText(p_sFullTextString, p_szCultureName, p_lOrganisationId, p_lFolderTypeId) as List<Document>;

                if (l_oDocuments_FullTextSearch.Count > 0)
                {
                    var L_GroupList = new List<Group>(l_oUser.GroupList);
                    var L_bCanBeConsul = false;

                    foreach (Document L_oDocument in l_oDocuments_FullTextSearch)
                    {
                        if (L_oDocument.ItemRank.Equals("000000000000"))
                        {
                            l_oDocumentsCopy.Add(L_oDocument);
                        }
                        else
                        {
                            var L_oSelectedItemInTreeView = l_oFolderTypeRepository.LstItems.Where(x => x.Code.Equals(L_oDocument.ItemRank)).FirstOrDefault();

                            if (L_oSelectedItemInTreeView != null)
                            {
                                foreach (Group grp in L_GroupList)
                                {
                                    // TOSEEFORLATER : Not implemented right now in RIO but normally to do : "(if (grp.IsAdministrator) return true;)"
                                    var L_oItemRightsList = new List<ItemRights>(grp.ItemRightsList);

                                    var L_oSelectedItemRights = GetItemsRights(L_oItemRightsList, L_oSelectedItemInTreeView);
                                    if (L_oSelectedItemRights != null)
                                    {
                                        if (L_oSelectedItemRights.CanConsult)
                                        {
                                            L_bCanBeConsul = true;
                                            break;
                                        }
                                    }
                                }
                                if (L_bCanBeConsul)
                                {
                                    l_oDocumentsCopy.Add(L_oDocument);
                                    L_bCanBeConsul = false;
                                }
                            }
                        }
                    }
                }

                //We build a list of folder based on the documents resulting from the full text search
                foreach (Document l_oDoc in l_oDocumentsCopy)
                {
                    if (!l_oFolders_FullTextSearch.Any(folder => folder.Identifier == l_oDoc.Folder.Identifier))
                    {
                        l_oFolders_FullTextSearch.Add(l_oDoc.Folder);
                    }
                }
                
                if (!String.IsNullOrEmpty(l_oCriteria))
                {
                    switch (p_sOperator)
                    {
                        case "AND":
                            //The case "AND" means that we return all the documents resulting of the full search having a corresponding Identifier into the document search results

                            foreach (Folder l_oFold in l_oFolders_FullTextSearch)
                            {
                                
                                var l_oFolder = l_oFolders_FolderSearch.Where(f => f.Identifier == l_oFold.Identifier).FirstOrDefault();
                                if (l_oFolder != null)
                                {
                                    var l_IoDocListName = from l_oDoc in l_oDocumentsCopy where l_oDoc.Folder.Identifier == l_oFolder.Identifier select l_oDoc.ImageName;
                                   var l_oDocListName = new List<string>(l_IoDocListName);
                                    if (l_oDocListName != null)
                                    {
                                        l_oFolder.FullTextDocList = l_oDocListName;
                                    }
                                    
                                    l_oFolders_Final.Add(l_oFolder);
                                }
                            }
                            break;

                        case "OR":
                            //The case "OR" means that we return the documents of both search, removing identical documents
                            l_oFolders_Final = l_oFolders_FolderSearch;
                            if (l_oDocumentsCopy != null && l_oDocumentsCopy.Count > 0)
                            {
                                foreach (Folder l_oFold in l_oFolders_FullTextSearch)
                                {
                                    var l_oFolder = l_oFolders_Final.Where(f => f.Identifier == l_oFold.Identifier).FirstOrDefault();
                                    if (l_oFolder == null)
                                    {
                                        var l_IoDocListName = from l_oDoc in l_oDocumentsCopy where l_oDoc.Folder.Identifier == l_oFold.Identifier select l_oDoc.ImageName;
                                        var l_oDocListName = new List<string>(l_IoDocListName);
                                        if (l_oDocListName != null)
                                        {
                                            l_oFold.FullTextDocList = l_oDocListName;
                                        }
                                        l_oFolders_Final.Add(l_oFold);
                                    }
                                }
                            }
                            break;
                    }
                }
                else
                {
                    l_oFolders_Final = new List<Folder>();
                    foreach (Folder l_oFold in l_oFolders_FullTextSearch)
                    {
                        var l_IoDocListName = from l_oDoc in l_oDocumentsCopy where l_oDoc.Folder.Identifier == l_oFold.Identifier select Path.Combine(l_oDoc.RelativePath,l_oDoc.ImageName);
                        var l_oDocListName = new List<string>(l_IoDocListName);
                        if (l_oDocListName != null)
                        {
                            l_oFold.FullTextDocList = l_oDocListName;
                        }
                        l_oFolders_Final.Add(l_oFold);
                    }
                    
                }
            }
            catch (Exception ex)
            {
                var l_oFolder = new Folder("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_sOperator<" + p_sOperator + "> p_sFullTextString<" + p_sFullTextString + ">)...)", ex);


                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetFoldersWithFullSearch : " + l_oFolder.FullErrorMessage);
                l_oFolders_Final.Add(l_oFolder);
            }

            //Add nb document
            FolderRepository.AddNbDocument(ref l_oFolders_Final, GetUser().UserId, p_lFolderTypeId);
            
            return l_oFolders_Final;
        }

        /// <summary>
        /// Add a document in our EDM
        /// </summary>
        /// <param name="p_lOrganisationId">Organisation ID</param>
        /// <param name="p_lFolderTypeId">FolderType ID</param>
        /// <param name="p_oDicValorization">Collection of valorization of index</param>
        /// <param name="p_szSourceDocumentName">Original document name</param>
        /// <param name="p_szItem">Code for Item where the document is associated</param>
        /// <param name="p_szNote">Notes associated at document</param>
        /// <param name="p_szAuthor">Author of document</param>
        /// <param name="p_szVideoLenght">Video Lenght</param>
        /// <param name="chronoName">Name of the chrono.</param>
        /// <param name="chronoId">The chrono id.</param>
        /// <param name="p_bFullTextRequested">Indicate if a fulltext is requested for this document</param>
        /// <returns>
        /// Retreive the DocumentId and the fullPath of file
        /// </returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<Document> AddDocument(long p_lOrganisationId, long p_lFolderTypeId, Dictionary<long, string> p_oDicValorization,
            List<string> p_szSourceDocumentName, string p_szItem,
            string p_szNote, string p_szAuthor, string p_szVideoLenght, string chronoName, long chronoId, bool p_bFullTextRequested
            )
        {
            return AddDocumentCore(p_lOrganisationId, p_lFolderTypeId, p_oDicValorization,
             p_szSourceDocumentName, null, p_szItem,
             p_szNote, p_szAuthor, p_szVideoLenght, chronoName, chronoId, p_bFullTextRequested);
        }

        /// <summary>
        /// Add indexdation to existing file in our EDM
        /// </summary>
        /// <param name="p_lOrganisationId">Organisation ID</param>
        /// <param name="p_lFolderTypeId">FolderType ID</param>
        /// <param name="p_oDicValorization">Collection of valorization of index</param>
        /// <param name="p_szSourceDocumentName">Original document name</param>
        /// <param name="p_szFolderPath">For an existing file in our EDM</param>
        /// <param name="p_szItem">Code for Item where the document is associated</param>
        /// <param name="p_szNote">Notes associated at document</param>
        /// <param name="p_szAuthor">Author of document</param>
        /// <param name="p_szVideoLenght">Video Lenght</param>
        /// <param name="chronoName">Name of the chrono.</param>
        /// <param name="chronoId">The chrono id.</param>
        /// <param name="p_bFullTextRequested">Indicate if a fulltext is requested for this document</param>
        /// <returns>
        /// Retreive the DocumentId and the fullPath of file
        /// </returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<Document> AddIndexationToExistingFile(long p_lOrganisationId, long p_lFolderTypeId, Dictionary<long, string> p_oDicValorization,
            List<string> p_szSourceDocumentName, Dictionary<string, string> p_szFolderPath, string p_szItem,
            string p_szNote, string p_szAuthor, string p_szVideoLenght, string chronoName, long chronoId, bool p_bFullTextRequested
            )
        {
            return AddDocumentCore(p_lOrganisationId, p_lFolderTypeId, p_oDicValorization,
             p_szSourceDocumentName, p_szFolderPath, p_szItem,
             p_szNote, p_szAuthor, p_szVideoLenght, chronoName, chronoId, p_bFullTextRequested);

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_lOrganisationId">Organisation identifier</param>
        /// <param name="p_lFolderTypeId">FolderType identifier</param>
        /// <param name="p_szNote"></param>
        /// <param name="p_szCreditPhoto"></param>
        /// <param name="p_szAuteur"></param>
        /// <param name="p_szFichierOrigine"></param>
        /// <returns></returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<OccurenciesByFolder> GetInfosValuesByFolderTypeId(long p_lOrganisationId, long p_lFolderTypeId, string p_szNote = null, string p_szCreditPhoto = null, string p_szAuteur = null, string p_szFichierOrigine = null)
        {
            var l_oRet = new List<OccurenciesByFolder>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + "> p_szNote<" + p_szNote + "> p_szCreditPhoto<" + p_szCreditPhoto + ">p_szAuteur<" + p_szAuteur + "> p_szFichierOrigine<" + p_szFichierOrigine + ">)...");
                var l_oDocuments = new List<Document>(SearchDocuments(p_lOrganisationId, p_lFolderTypeId, p_szNote, p_szCreditPhoto, p_szAuteur, p_szFichierOrigine));

                var l_oNoteList = new List<string>();
                var l_oPhotoCreditList = new List<string>();
                var l_oAuteur = new List<string>();
                var l_oFichierOrigine = new List<string>();

                foreach (Document l_oElement in l_oDocuments)
                {
                    if (string.IsNullOrWhiteSpace(l_oElement.Note) == false)
                        l_oNoteList.Add(l_oElement.Note);
                    if (string.IsNullOrWhiteSpace(l_oElement.PhotoCredit) == false)
                        l_oPhotoCreditList.Add(l_oElement.PhotoCredit);
                    if (string.IsNullOrWhiteSpace(l_oElement.Author) == false)
                        l_oAuteur.Add(l_oElement.Author);
                    if (string.IsNullOrWhiteSpace(l_oElement.OriginalNameFile) == false)
                        l_oFichierOrigine.Add(l_oElement.OriginalNameFile);
                }

                // Dispatch this to an Entity object
                l_oRet.Add(new OccurenciesByFolder(l_oNoteList, l_oPhotoCreditList, l_oAuteur, l_oFichierOrigine ));
            }
            catch (Exception ex)
            {
                var l_oFolder = new OccurenciesByFolder("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetInfosValuesByFolderTypeId : " + l_oFolder.FullErrorMessage);
                l_oRet.Add(l_oFolder);
            }
            return l_oRet;
        }

        /// <summary>
        /// Process a fullText search
        /// </summary>
        /// <param name="p_szSearchFilter">Criterias to find</param>
        /// <param name="p_szCultureName">Name of the P_SZ culture.</param>
        /// <param name="p_lOrganisationId">The P_L organisation id.</param>
        /// <param name="p_lFolderTypeId">The P_L folder type id.</param>
        /// <returns></returns>
        [Query(HasSideEffects=true)]
        public IEnumerable<Document> SearchFullText(string p_szSearchFilter, string p_szCultureName, long p_lOrganisationId, long p_lFolderTypeId )
        {
            var l_oRet = new List<Document>();
            var l_oCurrentUser = GetUser();
            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_szSearchFilter<" + p_szSearchFilter + "> p_szCultureName<" + p_szCultureName + "> in folder<" + SettingsManager.cStoreSettings.FullText_PathIndex + ">)...");
                var l_oReader = IndexReader.Open(SettingsManager.cStoreSettings.FullText_PathIndex);
                Searcher l_oSearcher = new IndexSearcher(l_oReader);

                QueryParser l_oParser;
                switch (p_szCultureName)
                {
                    case "en-US":
                        l_oParser = new QueryParser("contenu", new StandardAnalyzer());
                        break;
                    default:
                        l_oParser = new QueryParser("contenu", new FrenchAnalyzer());
                        break;
                }


                bool l_bStartWithAStar = false;
                if (p_szSearchFilter.Equals("*"))
                {
                    l_bStartWithAStar = true;
                }
                while(p_szSearchFilter.StartsWith("*") || p_szSearchFilter.StartsWith("?"))
                {
                    p_szSearchFilter = p_szSearchFilter.Substring(1, p_szSearchFilter.Length);
                }
                if (l_bStartWithAStar)
                {
                    p_szSearchFilter = "%" + p_szSearchFilter;
                }
                var l_oQuery = l_oParser.Parse(p_szSearchFilter.ToUpper(CultureInfo.CurrentCulture));

                var l_oHits = l_oSearcher.Search(l_oQuery);

                var l_oFolderTypeRepository = new FolderTypeRepository();
                GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);

                for (int i = 0; i < l_oHits.Length(); i++)
                {
                    Lucene.Net.Documents.Document l_oDocLucene = l_oHits.Doc(i);
                    
                    var l_oDocument = DocumentRepository.GetDocumentByRdImage(l_oCurrentUser.UserId, l_oDocLucene.Get("rd_idimage"), l_oFolderTypeRepository);
                    if (l_oDocument != null && !l_oDocument.Deleted)
                    {
                        l_oRet.Add(l_oDocument);
                    }
                }

                l_oSearcher.Close();
            }
            catch (Exception ex)
            {
                var l_oDocument = new Document("(p_szSearchFilter<" + p_szSearchFilter + "> p_szCultureName<" + p_szCultureName + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in SearchFullText : " + l_oDocument.FullErrorMessage);
                l_oRet.Add(l_oDocument);
            }
            ToolsDS.CleanMemory();
            return l_oRet;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_szSearchFilter"></param>
        /// <param name="p_szCultureName"></param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public bool GetFullTextMaxResultControl(string p_szSearchFilter, string p_szCultureName)
        {
            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_szSearchFilter<" + p_szSearchFilter + "> p_szCultureName<" + p_szCultureName + "> in folder<" + SettingsManager.cStoreSettings.FullText_PathIndex + ">)...");
                var l_oReader = IndexReader.Open(SettingsManager.cStoreSettings.FullText_PathIndex);
                Searcher l_oSearcher = new IndexSearcher(l_oReader);

                QueryParser l_oParser;
                switch (p_szCultureName)
                {
                    case "en-US":
                        l_oParser = new QueryParser("contenu", new StandardAnalyzer());
                        break;
                    default:
                        l_oParser = new QueryParser("contenu", new FrenchAnalyzer());
                        break;
                }


                bool l_bStartWithAStar = false;
                if (p_szSearchFilter.Equals("*"))
                {
                    l_bStartWithAStar = true;
                }
                while (p_szSearchFilter.StartsWith("*") || p_szSearchFilter.StartsWith("?"))
                {
                    p_szSearchFilter = p_szSearchFilter.Substring(1, p_szSearchFilter.Length);
                }
                if (l_bStartWithAStar)
                {
                    p_szSearchFilter = "%" + p_szSearchFilter;
                }
                var l_oQuery = l_oParser.Parse(p_szSearchFilter.ToUpper(CultureInfo.CurrentCulture));

                var l_oHits = l_oSearcher.Search(l_oQuery);

                ToolsDS.CleanMemory();

                if (l_oHits.Length() <= SettingsManager.cStoreSettings.FullText_MaxFullTextResult)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch ( Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in SearchFullText : " + ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_sMailSubject">Mail subject</param>
        /// <param name="p_sBody">Mail body</param>
        /// <param name="p_oMailAdressToList">Mail adresses</param>
        /// <param name="p_oFilesName">Attach files</param>
        /// <param name="p_oOriginalFileName"></param>
        [Invoke(HasSideEffects=true)]
        public void SendEMail(string p_sMailSubject, string p_sBody, string[] p_oMailAdressToList, List<string> p_oFilesName = null , List<string> p_oOriginalFileName = null)
        {
            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_sMailSubject<" + p_sMailSubject + "> p_sBody<" + p_sBody + ">)...");
                var l_oUser = GetUser();

                // Add a historic of user action
                AddActionHistoric((int)Constant.UserActions.ENVOI_PAR_MAIL, 0, 0, null, p_oFilesName.ToString(";"));

                var l_oMailAdressToList = new List<MailAddress>();
                foreach (string l_sMailAdress in p_oMailAdressToList)
                {
                    l_oMailAdressToList.Add(new MailAddress(l_sMailAdress, ""));
                }
                Smtp.SendMail(SettingsManager.cStoreSettings.Parameter_Smtp, "[RIO - Envoi document] " + p_sMailSubject, "<br><br>" +  p_sBody, new MailAddress(l_oUser.Email, ""), l_oMailAdressToList, p_oFilesName, p_oOriginalFileName, SettingsManager.cStoreSettings.Parameter_SmtpLogin, SettingsManager.cStoreSettings.Parameter_SmtpPassword);

            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in SendEMail : " + ex.Message);
            }
            
        }

        #region Versioning

        /// <summary>
        /// Add a version to the specified document from a file
        /// </summary>
        /// <param name="p_lDocId">Document identifier</param>
        /// <param name="p_lUserId">Current user identifier</param>
        /// <param name="p_sFileName">New filename without path</param>
        /// <returns>
        /// Return the new version if ok
        /// Return ErrorCode=1 for add version create error
        /// </returns>
        [Query]
        public IEnumerable<VersioningItem> AddVersionFromFile(long p_lDocId, string p_sFileName, long p_lModelId, bool IsMajor)
        {
            var l_oRet = new List<VersioningItem>();
            try
            {

                VersioningItem version = new VersioningItem();

                var l_oUser = GetUser();
                long newid = DocumentRepository.AddVersion(p_lDocId, l_oUser.UserId, p_sFileName, p_lModelId, IsMajor);
                AddActionHistoric((int)Constant.UserActions.AJOUT_VERSION, 0, 0, p_lDocId.ToString(), p_sFileName);

                if (newid > 0)
                {
                    version = DocumentRepository.GetVersion(newid);
                }
                else
                {
                    version.IsValid = false;
                    version.ErrorMessage = string.Format("AddVersionFromFile error - Could not create new version for document:{0}, result={1}", p_lDocId, newid);
                    NetBay.Core.Log.LogManager.Instance().LogError(version.ErrorMessage);
                }
                l_oRet.Add(version);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in AddVersionFromFile : " + ex.Message);
                var version = new VersioningItem();
                version.ErrorMessage = string.Format("Exception in AddVersionFromFile : " + ex.Message);
                l_oRet.Add(version);
            }
            return l_oRet;
        }

        /// <summary>
        /// Add a version to the specified document from an old version
        /// </summary>
        /// <param name="p_lDocId">Document identifier</param>
        /// <param name="p_lUserId">Current user identifier</param>
        /// <param name="p_oOldVersion">Old Version</param>
        /// <returns>
        /// Return the new version if ok
        /// Return ErrorCode=1 for add version create error
        /// </returns>
        [Invoke(HasSideEffects = true)]
        public IEnumerable<VersioningItem> AddVersionFromOldVersion(long p_lDocId, VersioningItem p_oOldVersion, long p_lModelId, bool IsMajor)
        {
            var l_oRet = new List<VersioningItem>();
            try
            {
                VersioningItem version = new VersioningItem();
                var l_oUser = GetUser();
                long newid = DocumentRepository.AddVersionFromOld(p_lDocId, l_oUser.UserId, p_oOldVersion.VersionId, p_lModelId, IsMajor);
                AddActionHistoric((int)Constant.UserActions.AJOUT_VERSION, 0, 0, p_lDocId.ToString(), null);

                if (newid > 0)
                {
                    version = DocumentRepository.GetVersion(newid);
                }
                else
                {
                    version.IsValid = false;
                    version.ErrorMessage = string.Format("AddVersionFromOldVersion error - Could not create new version for document:{0}, result={1}", p_lDocId, newid);
                    NetBay.Core.Log.LogManager.Instance().LogError(version.ErrorMessage);
                }
                l_oRet.Add(version);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in AddVersionFromOldVersion : " + ex.Message);
                var version = new VersioningItem();
                version.ErrorMessage = string.Format("Exception in AddVersionFromOldVersion : " + ex.Message);
                l_oRet.Add(version);
            }
            return l_oRet;
        }

        /// <summary>
        /// Add a version to the specified document from an old version
        /// </summary>
        /// <param name="p_lDocId">Document identifier</param>
        /// <param name="p_lUserId">Current user identifier</param>
        /// <param name="p_oOldVersion">Old Version</param>
        /// <returns>
        /// Return the new version if ok
        /// Return ErrorCode=1 for add version create error
        /// </returns>
        [Invoke(HasSideEffects = true)]
        public IEnumerable<VersioningItem> OverwriteVersion(long p_lDocId, string p_sFileName)
        {
            var l_oRet = new List<VersioningItem>();
            try
            {
                VersioningItem version = new VersioningItem();
                var l_oUser = GetUser();
                long newid = 0;
                newid = DocumentRepository.OverwriteVersion(p_lDocId, l_oUser.UserId, p_sFileName);
                AddActionHistoric((int)Constant.UserActions.AJOUT_VERSION, 0, 0, p_lDocId.ToString(), null);

                if (newid > 0)
                {
                    version = DocumentRepository.GetVersion(newid);
                }
                else
                {
                    version.IsValid = false;
                    version.ErrorMessage = string.Format("OverwriteVersion error - Could not create new version for document:{0}, result={1}", p_lDocId, newid);
                    NetBay.Core.Log.LogManager.Instance().LogError(version.ErrorMessage);
                }

                l_oRet.Add(version);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in OverwriteVersion : " + ex.Message);
                var version = new VersioningItem();
                version.ErrorMessage = string.Format("Exception in OverwriteVersion : " + ex.Message);
                l_oRet.Add(version);
            }
            return l_oRet;
        }

        /// <summary>
        /// Check if a document have a version in checkout
        /// </summary>
        /// <returns>Status of execution</returns>
        [Invoke(HasSideEffects = true)]
        public VersioningItem GetCurrentVersion(long p_lDocId)
        {
            VersioningItem version = new VersioningItem();
            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocId<" + p_lDocId + ">");
                long newid = DocumentRepository.GetCurrentVersion(p_lDocId);
                version = DocumentRepository.GetVersion(newid);
            }
            catch (Exception ex)
            {
                version = new VersioningItem("(<p_lDocId" + p_lDocId + ">) " + ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetCurrentVersion : " + ex.Message);
            }
            return version;
        }

        /// <summary>
        /// Check if a document have a version in checkout
        /// </summary>
        /// <returns>Status of execution</returns>
        [Invoke(HasSideEffects = true)]
        public VersioningItem GetLastVersion(long p_lDocId)
        {
            VersioningItem version = new VersioningItem();
            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lDocId<" + p_lDocId + ">");
                version = DocumentRepository.GetLastVersion(p_lDocId);
            }
            catch (Exception ex)
            {
                version = new VersioningItem("(<p_lDocId" + p_lDocId + ">) " + ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetCurrentVersion : " + ex.Message);
            }
            return version;
        }

        #endregion

        #region Paste Document

        /// <summary>
        /// Paste the list of documents identifiers in the destination folder. 
        /// </summary>
        /// <param name="DocId">list of document identifier.</param>
        /// <param name="DestinationFolderIdentifier">Destination folder identifier.</param>
        /// <param name="isCut">A value indicating whether the action is a copy or cut action.</param>
        /// <param name="ItemRank">Item rank in the destination folder.</param>
        /// <param name="isOriginalVersion">A value indicating whether the document in the list is an old version.</param>
        /// <returns></returns>
        [Invoke]
        public ReturnBoolean PasteDocument(List<long> DocId, string DestinationFolderIdentifier, long FolderIdentifier, long DestinationFolderTypeId,  bool isCut, string ItemRank, long VersionId, bool isOriginalVersion)
        {
            ReturnBoolean result = new ReturnBoolean();
            try
            {
                // Set to unclassified if empty
                if (string.IsNullOrEmpty(ItemRank))
                {
                    ItemRank = "000000000000";
                }

                if (VersionId == 0)
                {
                    isOriginalVersion = true;
                }

                //Call repository for each documents 
                foreach (long id in DocId)
                {
                    NetBay.Core.Log.LogManager.Instance().LogDebug("Paste document (p_lDocId<" + id + ">");
                    DocumentRepository.PasteDocument(id, DestinationFolderIdentifier, FolderIdentifier, DestinationFolderTypeId, isCut, ItemRank, isOriginalVersion, VersionId);
                     
                    // Add historic
                    if (isCut)
                        AddActionHistoric((int)Constant.UserActions.DOCUMENT_COUPER, DestinationFolderTypeId, 0, id.ToString(), null);
                    else
                        AddActionHistoric((int)Constant.UserActions.DOCUMENT_COPIER, DestinationFolderTypeId, 0, id.ToString(), null);
                }

                result.Value = true;
            }
            catch (Exception ex)
            {
                result = new ReturnBoolean(ex.Message);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in PasteDocument : " + ex.Message);
            }
            return result;
        }

        #endregion

        #region Private
        /// <summary>
        /// Adds the document core.
        /// </summary>
        /// <param name="OrganisationId">The organisation id.</param>
        /// <param name="FolderTypeId">The folder type id.</param>
        /// <param name="DicValorization">The dic valorization.</param>
        /// <param name="SourceDocumentName">Name of the source document.</param>
        /// <param name="FolderPath">The folder path.</param>
        /// <param name="Item">The item.</param>
        /// <param name="Note">The note.</param>
        /// <param name="Author">The author.</param>
        /// <param name="VideoLenght">The video lenght.</param>
        /// <param name="ChronoName">Name of the chrono.</param>
        /// <param name="ChronoId">The chrono id.</param>
        /// <param name="FullTextRequested">if set to <c>true</c> [full text requested].</param>
        /// <param name="p_szIdCourrierErp">The P_SZ id courrier erp.</param>
        /// <param name="p_szMesureErp">The P_SZ mesure erp.</param>
        /// <returns></returns>
        internal List<Document> AddDocumentCore(long OrganisationId, long FolderTypeId, Dictionary<long, string> DicValorization,
            List<string> SourceDocumentName, Dictionary<string, string> FolderPath, string Item,
            string Note, string Author, string VideoLenght, string ChronoName, long ChronoId, bool FullTextRequested,
            string p_szIdCourrierErp = "", string p_szMesureErp =""
            )
        {
            var l_oRet = new List<Document>();

            try
            {

                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + OrganisationId + "> p_lFolderTypeId<" + FolderTypeId + "> p_oDicValorization<" + DicValorization + ">)...");
                FolderTypeRepository l_oFolderTypeRepository;
                var l_oUser = GetFolderTypeRepository(OrganisationId, FolderTypeId, out l_oFolderTypeRepository);

                // Create the list of combination Index and its value
                var l_oDicIndexValorization = RebuildDictionaryIndex(DicValorization, l_oFolderTypeRepository.LstIndex);

                if (SourceDocumentName != null && SourceDocumentName.Count > 0)
                {
                    List<long> addedDocumentId = new List<long>();
                    wkfConditionType wkfStartingCondition = wkfConditionType.AddDocument;

                    #region Build Folder
                    // Retreive the reference Date
                    var l_oDateRef = DateTime.Now;
                    // Create the Guid for us
                    var l_szGuidRef = l_oDateRef.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
                    l_szGuidRef += Guid.NewGuid().ToString("N");

                    bool folderCreated = false;
                    var l_lFolderID = CreateFolder(l_oUser, FolderTypeId, l_oFolderTypeRepository, l_oDicIndexValorization, l_szGuidRef, out folderCreated);

                    //If the folder has been created we must update the starting condition
                    if (folderCreated)
                        wkfStartingCondition = wkfConditionType.AddFolder;

                    // Retreive the 'r_id_doc'
                    var l_oFolder = l_oFolderTypeRepository.GetFolderByFolderId(l_lFolderID);
                    #endregion

                    List<Document> l_oDocumentToAdd = new List<Document>();


                    foreach (string l_oDocumentName in SourceDocumentName)
                    {
                        l_szGuidRef = l_oDateRef.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
                        l_szGuidRef += Guid.NewGuid().ToString("N");

                        // Build the final document name and the final path
                        var l_szDocumentName = string.Empty;
                        var l_szFolderPath = string.Empty;   // "20/2010/04/26/14/30/41"

                        // Retreive the extension
                        var l_szExtension = Path.GetExtension(l_oDocumentName);

                        // Build the final document name
                        l_szDocumentName = l_szGuidRef;
                        l_szDocumentName += "_US";
                        l_szDocumentName += l_oUser.UserId;
                        l_szDocumentName += l_szExtension;

                        if (FolderPath != null && FolderPath.Count > 0)
                        {
                            l_szFolderPath = FolderPath.Where(f => f.Key.Equals(l_oDocumentName)).FirstOrDefault().Value;
                        }

                        if (string.IsNullOrWhiteSpace(l_szFolderPath))
                        {
                            // Build the final path
                            var l_szYear = l_oDateRef.ToString("yyyy");
                            var l_szMonth = l_oDateRef.ToString("MM");
                            var l_szDay = l_oDateRef.ToString("dd");
                            var l_szHour = l_oDateRef.ToString("HH");
                            var l_szMinutes = l_oDateRef.ToString("mm");
                            var l_szSeconds = l_oDateRef.ToString("ss");
                            l_szFolderPath = string.Format(@"{0}\{1}\{2}\{3}\{4}\{5}\{6}" , OrganisationId, l_szYear, l_szMonth, l_szDay, l_szHour, l_szMinutes, l_szSeconds);
                        }
                        else
                        {
                            // We have in 'l_szFolderPath' something like 'OrganisationId\Year\Month\Day\Hour\Minutes\Seconds\DocumentName'
                            l_szDocumentName = Path.GetFileName(l_szFolderPath);
                            l_szFolderPath = Path.GetDirectoryName(l_szFolderPath);
                        }

                        //Build document
                        Document d = new Document
                                         {
                                             FolderTypeIdentifier = FolderTypeId,
                                             FolderId = l_lFolderID,
                                             FolderIdentifier = l_oFolder.Iddoc,
                                             RelativePath = l_szFolderPath,
                                             ImageName = l_szDocumentName,
                                             OriginalNameFile = l_oDocumentName,
                                             ItemRank = string.IsNullOrEmpty(Item) ? "000000000000" : Item,
                                             Note = Note,
                                             Author = Author,
                                             PhotoCredit = ChronoName,
                                             VideoLength = VideoLenght,
                                             IdCourrierErp = p_szIdCourrierErp,
                                             MesureErp = p_szMesureErp
                                         };
                        l_oDocumentToAdd.Add(d);

                    }

                    l_oRet = DocumentRepository.AddDocument(l_oDocumentToAdd, GetDocumentRank);

                    // Add historical
                    foreach (Document l_d in l_oRet)
                    {
                        addedDocumentId.Add(l_d.Identifier);
                        AddActionHistoric((int)Constant.UserActions.AJOUT_DOCUMENTS_DOSSIER, FolderTypeId, l_lFolderID, l_d.Identifier.ToString(), l_d.OriginalNameFile);
                    }

                    // Call workflow Controller 
                    WorkflowController.StartWorkflowDispatcher(FolderTypeId, l_lFolderID, wkfStartingCondition, GetUser().UserId, addedDocumentId, ChronoId, DicValorization);
                }
                else
                {
                    // Retreive the reference Date
                    var l_oDateRef = DateTime.Now;

                    // Create the Guid for us
                    var l_szGuidRef = l_oDateRef.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
                    l_szGuidRef += Guid.NewGuid().ToString("N");

                    bool folderCreated = false;
                    var l_lFolderID = CreateFolder(l_oUser, FolderTypeId, l_oFolderTypeRepository, l_oDicIndexValorization, l_szGuidRef, out folderCreated);

                    // Call workflow Controller 
                    WorkflowController.StartWorkflowDispatcher(FolderTypeId, l_lFolderID, wkfConditionType.AddFolder, GetUser().UserId, null, ChronoId);
                }

            }
            catch (Exception ex)
            {
                var l_oOneItem = new Document("(p_lOrganisationId<" + OrganisationId + "> p_lFolderTypeId<" + FolderTypeId + "> p_oDicValorization<" + DicValorization + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in AddDocumentCore : " + l_oOneItem.FullErrorMessage);
                l_oRet.Add(l_oOneItem);
            }
            return l_oRet;
        }

        /// <summary>
        /// Adds the document core to existing folder.
        /// </summary>
        /// <param name="p_lOrganisationId">The P_L organisation id.</param>
        /// <param name="p_lFolderTypeId">The P_L folder type id.</param>
        /// <param name="p_lFolderId">The P_L folder id.</param>
        /// <param name="p_szSourceDocumentName">Name of the P_SZ source document.</param>
        /// <param name="p_szFolderPath">The P_SZ folder path.</param>
        /// <param name="p_szItem">The P_SZ item.</param>
        /// <param name="p_szNote">The P_SZ note.</param>
        /// <param name="p_szAuthor">The P_SZ author.</param>
        /// <param name="p_szPhotoCredit">The P_SZ photo credit.</param>
        /// <param name="p_szVideoLenght">The P_SZ video lenght.</param>
        /// <param name="p_bFullTextRequested">The P_B full text requested.</param>
        /// <returns></returns>
        internal List<Document> AddDocumentCoreToExistingFolder(long p_lOrganisationId, long p_lFolderTypeId, long p_lFolderId,
                                                                List<string> p_szSourceDocumentName, Dictionary<string, string> p_szFolderPath, string p_szItem,
                                                                string p_szNote, string p_szAuthor, string p_szPhotoCredit, string p_szVideoLenght, long Rank, bool p_bFullTextRequested)
        {
            var l_oRet = new List<Document>();

            try
            {

                NetBay.Core.Log.LogManager.Instance().LogDebug("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + ">)...");

                FolderTypeRepository l_oFolderTypeRepository;
                var l_oUser = GetFolderTypeRepository(p_lOrganisationId, p_lFolderTypeId, out l_oFolderTypeRepository);

                List<Document> l_oDocumentToAdd = new List<Document>();

                // Retreive the 'r_id_doc'
                var l_oFolder = l_oFolderTypeRepository.GetFolderByFolderId(p_lFolderId);

                foreach (string l_oDocumentName in p_szSourceDocumentName)
                {
                    // Retreive the reference Date
                    var l_oDateRef = DateTime.Now;
                    // Create the Guid for us
                    var l_szGuidRef = l_oDateRef.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo);
                    l_szGuidRef += Guid.NewGuid().ToString("N");

                    // Build the final document name and the final path
                    var l_szDocumentName = string.Empty;
                    var l_szFolderPath = string.Empty;   // @"20/2010/04/26/14/30/41"

                    // Retreive the extension
                    var l_szExtension = Path.GetExtension(l_oDocumentName);

                    // Build the final document name
                    l_szDocumentName = l_szGuidRef;
                    l_szDocumentName += "_US";
                    l_szDocumentName += l_oUser.UserId;
                    l_szDocumentName += l_szExtension;

                    if (p_szFolderPath != null && p_szFolderPath.Count > 0)
                    {
                        l_szFolderPath = p_szFolderPath.Where(f => f.Key.Equals(l_oDocumentName)).FirstOrDefault().Value;
                    }

                    if (string.IsNullOrWhiteSpace(l_szFolderPath) == true)
                    {
                        // Build the final path
                        var l_szYear = l_oDateRef.ToString("yyyy");
                        var l_szMonth = l_oDateRef.ToString("MM");
                        var l_szDay = l_oDateRef.ToString("dd");
                        var l_szHour = l_oDateRef.ToString("HH");
                        var l_szMinutes = l_oDateRef.ToString("mm");
                        var l_szSeconds = l_oDateRef.ToString("ss");
                        l_szFolderPath = p_lOrganisationId + @"\" + l_szYear + @"\" + l_szMonth + @"\" + l_szDay + @"\" + l_szHour + @"\" + l_szMinutes + @"\" + l_szSeconds;
                    }
                    else
                    {
                        // We have in 'l_szFolderPath' something like 'OrganisationId\Year\Month\Day\Hour\Minutes\Seconds\DocumentName'
                        l_szDocumentName = Path.GetFileName(l_szFolderPath);
                        l_szFolderPath = Path.GetDirectoryName(l_szFolderPath);
                    }

                    Document d = new Document();
                    d.FolderTypeIdentifier = p_lFolderTypeId;
                    d.FolderId = p_lFolderId;
                    d.FolderIdentifier = l_oFolder.Iddoc;
                    d.RelativePath = l_szFolderPath;
                    d.ImageName = l_szDocumentName;
                    d.OriginalNameFile = l_oDocumentName;
                    d.ItemRank = string.IsNullOrEmpty(p_szItem) ? "000000000000" : p_szItem;
                    d.Note = p_szNote;
                    d.Author = p_szAuthor;
                    d.PhotoCredit = p_szPhotoCredit;
                    d.VideoLength = p_szVideoLenght;
                    d.MultiVolumePath = Path.ChangeExtension(Path.Combine(SettingsManager.cStoreSettings.Thumbnail_Directory, l_szFolderPath) + @"\" + l_szDocumentName, Constant.ImageFileFormat.JPG.szGetDescription());
                    l_oDocumentToAdd.Add(d);

                    l_oRet = DocumentRepository.AddDocument(l_oDocumentToAdd, GetDocumentRank);
                    foreach (Document l_d in l_oDocumentToAdd)
                    {
                        // Add a historic of user action
                        AddActionHistoric((int)Constant.UserActions.AJOUT_DOCUMENTS_DOSSIER, p_lFolderTypeId, p_lFolderId, l_d.Identifier.ToString(), l_d.OriginalNameFile);
                    }

                }
            }
            catch (Exception ex)
            {
                var l_oOneItem = new Document("(p_lOrganisationId<" + p_lOrganisationId + "> p_lFolderTypeId<" + p_lFolderTypeId + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in AddDocumentCoreToExistingFolder : " + l_oOneItem.FullErrorMessage);
                l_oRet.Add(l_oOneItem);
            }
            return l_oRet;
        }

        /// <summary>
        /// Get ItemRights from a group switch an item
        /// </summary>
        /// <param name="P_oItemRightsList">ItemRights from group</param>
        /// <param name="P_oItem">item to compare</param>
        /// <returns></returns>
        private ItemRights GetItemsRights(List<ItemRights> P_oItemRightsList, Item P_oItem)
        {
            return P_oItemRightsList.Where(x => x.Item.Identifier == P_oItem.Identifier).FirstOrDefault();
        }

        /// <summary>
        /// Creates the folder.
        /// </summary>
        /// <param name="p_oCurrentUser">The p_o current user.</param>
        /// <param name="p_lFolderTypeId">The P_L folder type id.</param>
        /// <param name="p_oFolderTypeRepository">The p_o folder type repository.</param>
        /// <param name="p_oDicValorization">The p_o dic valorization.</param>
        /// <param name="p_szGuidRef">The P_SZ GUID ref.</param>
        /// <param name="FolderHasCreated">The folder has created.</param>
        /// <returns></returns>
        private long CreateFolder(User p_oCurrentUser, long p_lFolderTypeId, FolderTypeRepository p_oFolderTypeRepository, Dictionary<Index, string> p_oDicValorization, string p_szGuidRef, out bool FolderHasCreated)
        {
            // Check if folder already exist
            FolderHasCreated = false;
            var l_oRetIsFolderExist = FolderRepository.IsFolderExist(p_oCurrentUser.UserId, p_lFolderTypeId, p_oFolderTypeRepository.Table, p_oDicValorization);
            if (l_oRetIsFolderExist.IsValid == false)
            {
                throw new Exception("Unable to know if FolderTypeId(" + p_lFolderTypeId + ") has some Folder", l_oRetIsFolderExist.ApplicationException);
            }
            var l_lFolderID = l_oRetIsFolderExist.Value;
            if (l_lFolderID == 0)
            {
                // Add the Folder
                l_lFolderID = AddFolder(p_oCurrentUser.UserId, p_lFolderTypeId, p_szGuidRef.Substring(0, 22), p_oFolderTypeRepository.Table, p_oDicValorization).Value;
                FolderHasCreated = true;
            }
            // Check if we have a folder to insert our document
            if (l_lFolderID == 0)
            {
                throw new Exception("Unable to add a Document because Folder is null!");
            }

            return l_lFolderID;
        }

        #endregion
    }
}
